# _*_ coding: utf-8 _*_
"""
@ 时间    ：2024/10/25 14:31
@ 作者    ：旺财
@ 文件    ：07 特征筛选WOE与IV值.py
@ 说明    ：   
"""
import pandas as pd
import numpy as np

# 1. 构造数据
df = pd.DataFrame([[22, 1], [25, 1], [20, 0], [35, 0], [32, 1], [38, 0], [50, 0], [46, 1]], columns=['年龄', '是否违约'])
print(df)

# 2. 数据封箱
df_cut = pd.cut(df['年龄'], 3)
print(df_cut)

# 3. 统计各个分箱的总样本数/坏样本数/好样本数并汇总数据
# 统计总客户数
cut_group_all = df['是否违约'].groupby(df_cut, observed=True).count()
# 统计违约客户数
cut_y = df['是否违约'].groupby(df_cut, observed=True).sum()
# 统计未违约客户数
cut_n = cut_group_all - cut_y
print(cut_group_all, cut_y, cut_n)
# 汇总基础数据
df_new = pd.DataFrame()
df_new['总数'] = cut_group_all
df_new['坏样本'] = cut_y
df_new['好样本'] = cut_n
print(df_new)

# 4. 统计坏样本与好样本的比例
df_new['坏样本%'] = df_new['坏样本'] / df_new['坏样本'].sum()
df_new['好样本%'] = df_new['好样本'] / df_new['好样本'].sum()

# 5. 计算WOE值
df_new['WOE'] = np.log(df_new['坏样本%'] / df_new['好样本%'])
print(df_new)
df_new['WOE'] = df_new['WOE'].map(lambda x: 0 if x in [np.inf, -np.inf] else x)  # 将无穷大替换为0

# 6. 计算各个分箱的IV值
df_new['IV'] = df_new['WOE'] * (df_new['坏样本%'] - df_new['好样本%'])
print(df_new)

# 7. 汇总各个分箱的IV值,获取特征变量的IV值
iv = df_new['IV'].sum()
print(f'特征变量 年龄 的IV值(重要程度)为{iv}')